// autor: Shelman
// description: 主要测试入口程序

#include <iostream>
#include <csignal>
#include <thread>
#include <chrono>
#include <ctime>
#include <string>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "Common/Common.h"
#include "TcpClient/TcpClient.h"
#include "TcpServer/TcpServer.h"
#include "UdpUtil/UdpUtil.h"
#include "FtpClient/FtpClient.h"

#include "Common/CommLogDef.h"

// 全局程序主线程运行标识
static bool gs_bRunningStatus = true;

// 响应系统信号事件处理接口，退出主线程
static void pfnExitMianThread(int signum)
{
    std::signal(signum, SIG_DFL); // 还原默认的信号处理
    gs_bRunningStatus = false;
    return;
}

static void pfnOnRecvData(const std::string &strData, int fd)
{
    COMMONLOG_INFO("0x%08p recv data: %s.", fd, strData.data());
    return;
}

// 测试TcpClient接口
void testTcpClient()
{
    TcpClient client;
    NetworkConnInfo stSrvConnInfo;
    stSrvConnInfo.strIP = "192.168.160.1";
    stSrvConnInfo.ui16Port = 8087;

    client.setDataRecvCallback(pfnOnRecvData);
    //bool ret = client.connect(stSrvConnInfo, false);
    bool ret = client.connect(stSrvConnInfo, true);
    std::cout << ">>>>>> Connection ret: " << ret << std::endl;

#if 0
    std::thread th([&client]() {
        client.sendData("this is test data......0123456789 aaaaa bbbbbbb cccc");
        std::this_thread::sleep_for(std::chrono::seconds(1));
    });
#endif

    // 主线程业务处理
    do {
        client.sendData("this is test data......0123456789 aaaaa bbbbbbb cccc");
        //std::this_thread::sleep_for(std::chrono::milliseconds(100));
        std::this_thread::sleep_for(std::chrono::seconds(1));
    } while (gs_bRunningStatus);

    client.disconnect();

    return;
}

// 测试TcpServer接口
void testTcpServer()
{
    TcpServer server;
    NetworkConnInfo stConnInfo;
    stConnInfo.strIP = "0.0.0.0";
    stConnInfo.ui16Port = 8087;

    // 设置回调
    server.setDataRecvCallback([&server](const std::string &strData, int fd) {
        COMMONLOG_INFO("Recv client (%s) data len (%lu), data: %s."
                       , server.getClientAddrInfo(fd).data()
                       , strData.size(), strData.data());

        server.sendData(fd, "[" +std::to_string((long)std::time(nullptr)) + "] Thank your message!!!");
        return;
    });

    server.start(stConnInfo);

    do {
        //std::this_thread::sleep_for(std::chrono::milliseconds(100));
        std::this_thread::sleep_for(std::chrono::seconds(1));
    } while (gs_bRunningStatus);

    server.stop();

    return;
}

// 测试UdpUtil接口
void testUdpUtil()
{
    NetworkConnInfo stConnInfo;
    stConnInfo.strIP = "0.0.0.0";
    stConnInfo.ui16Port = 56660;

    UdpUtil objUtil;
    objUtil.setDataRecvCallback([&objUtil](const std::string &strData
                                , const NetworkConnInfo &stConnInfo) {
        COMMONLOG_INFO("Recv remote (%s:%u) data: %s."
                       , stConnInfo.strIP.data(), stConnInfo.ui16Port
                       , strData.data());
        objUtil.sendData(stConnInfo, "Send back data in lamda function.");
        return;
    });

    objUtil.start(stConnInfo);

    do {
        NetworkConnInfo stRemoteConnInfo;
        stRemoteConnInfo.strIP = "192.168.10.5";
        stRemoteConnInfo.ui16Port = 60000;
        objUtil.sendData(stRemoteConnInfo, "this is test info");
        //std::this_thread::sleep_for(std::chrono::milliseconds(100));
        std::this_thread::sleep_for(std::chrono::seconds(1));
    } while (gs_bRunningStatus);

    objUtil.stop();

    return;
}

// 测试FtpClient接口
void testFtpClient()
{
    FtpClient ftp;

    // FTP服务器配置
    std::string server = "ftp.example.com"; // 192.168.10.3:21
    std::string username = "your-username";
    std::string password = "your-password";

    // 文件上传示例
    std::string localFile = "localfile.txt";
    std::string remoteFile = "remotefile.txt";

    if (ftp.uploadFile(server, username, password, localFile, remoteFile)) {
        std::cout << "Upload completed!" << std::endl;
    }

    // 文件下载示例
    std::string downloadedFile = "downloaded.txt";
    if (ftp.downloadFile(server, username, password, remoteFile, downloadedFile)) {
        std::cout << "Download completed!" << std::endl;
    }

    return;
}

// 主程序
int main(int argc, char **argv)
{
    std::signal(SIGINT, pfnExitMianThread);

    // 根据输出判断进入哪个分支的测试
    if (2 <= argc) {
        if (0 == strcmp(argv[1], "client")) {
            testTcpClient();
        } else if (0 == strcmp(argv[1], "server")) {
            testTcpServer();
        } else if (0 == strcmp(argv[1], "udp")) {
            testUdpUtil();
        } else if (0 == strcmp(argv[1], "ftp-client")) {
            testFtpClient();
        } else {
            std::cerr << ">>>>>> Unsupport test case!" << std::endl;
            return -1;
        }
    } else {
        std::cerr << ">>>>>> Input parameters error!" << std::endl;
        return -1;
    }

    return 0;
}
